Rem
mscchat buildtool - simple chat build tool and updater, part of mscchat

Copyright (c) 2009 Michael Schaefer and Immo-Gert Birn

This program is free software: you can redistribute it And/Or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, Or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY Or FITNESS For A PARTICULAR PURPOSE.  See the
GNU General Public License For more details.

You should have received a copy of the GNU General Public License
along with this program.  If Not, see <http://www.gnu.org/licenses/>.
EndRem

Rem
Hilfsprogramm zum bauen unf FTPen von Superchat

Benoetigt werden:
o svn, svnversion
o Blitzmax mit MaxGUI.mod, bah.regex und bah.libcurl

End Rem

Import BaH.libcurl
Import BaH.RegEx

SuperStrict

Include "version.bmx"
Include "igbftp.bmx"

' Actions
Const g_version:String = "1.02, 03.08.2009"
Global g_actions:String[][] = [["help " , "Hilfetext anzeigen (Default)"], ..
                               ["build", "Client, Server und Buildtool bauen"], ..
                               ["ftp  "  , "Client , Server und Buildtool bauen und per FTP hochladen"]]  
'help ist die Default-aktion
Const c_action_build:Int   = 1
Const c_action_ftp:Int     = 2

' die bmx-Dateien (bekommen noch .bmx angehaengt)
Global  progs:String[][]     = [["guichatclient", "1"], ["chatserver", "0"], ["buildtool", "0"]]
' die Namen der ausfuehrbaren dateien
Global  exenames:String[progs.length]

?Win32
  Global c_Make_dir:String = String(getenv_("TMP")) + "/mscchat-updater"
'  Local  prog_dir:String   = getenv_("ProgramFiles")
  Global bmk:String        = "c:\BlitzMax\bin\bmk.exe"
  For Local i:Int = 0 To progs.length - 1
     exenames[i] = progs[i][0] + ".exe"
  Next
?Linux
  Global c_Make_dir:String = "/tmp/mscchat-updater"
  Local home:String        = String(getenv_("HOME")) 
  Global bmk:String        = home + "/BlitzMax/bin/bmk"
  For Local i:Int = 0 To progs.length - 1
     exenames[i] = progs[i][0]
  Next
? 'Ende bedingte Anweisungen

For Local i:Int = 0 To progs.length - 1
  progs[i][0] :+ ".bmx"
Next


Global olddir:String = CurrentDir()

'------------------------------------------------------------------------------------
' Hauptprogramm
'------------------------------------------------------------------------------------

' Herausfinden, was zu tun ist
Local action:Int = get_action()
' es ist was zu tun => Header ausgeben
zeige_hilfe(True)
init_directory()

' Jetzt ist c_make_dir das aktuelle Verzeichnis
Local source_version:Int = sync_files()
Local ftp_version:Int = get_ftp_version(action)
build(action,source_version,ftp_version)
upload(action,source_version,ftp_version)

cleanup(action)

'------------------------------------------------------------------------------------
' Ende des Hauptprogramms, Beginn der Funktionen
'------------------------------------------------------------------------------------

'------------------------------------------------------------------------------------
' Kommandozeile auswerten
'------------------------------------------------------------------------------------
Function get_action:Int()
  If AppArgs.length > 2 Or AppArgs.length = 1 Then
    zeige_hilfe()
    End
  EndIf

  ' Schleife von 1 weil Aktion 0 "help" ist
  For Local i:Int = 1 To g_actions.length - 1
    If AppArgs[1].toLower() = g_actions[i][0].Trim() Then Return i
  Next
  zeige_hilfe()
  End
EndFunction

'------------------------------------------------------------------------------------
' Hilfe anzeigen
'------------------------------------------------------------------------------------
Function zeige_hilfe(nur_version:Int = Null)
  Print "~n-----------------------------------------------------------------"
  Print "Program " + AppArgs[0] + ", Version " + g_version
  Print "SVN-Revision: " + svn_revision
  Print "-----------------------------------------------------------------"
  Print "MSCCHAT Kompilier- und Upload- Hilfsprogram"
  Print "-----------------------------------------------------------------"
  If nur_version Then Return
  Print "Moegliche Argumente:"
  For Local i:Int = 0 To g_actions.length - 1
    Print "  " + g_actions[i][0] + "~t" + g_actions[i][1]
  Next
  Print "-----------------------------------------------------------------~n"
EndFunction

'------------------------------------------------------------------------------------
' Verzeichnis erstellen
'------------------------------------------------------------------------------------
Function init_directory:String()
  Print "Benutze Verzeichnis " + c_make_dir

  Local success:Int
  Local dir:String = ReadDir(c_make_dir)
  If dir <> "0" Then
    success = DeleteDir(c_make_dir, True)
    If Not success my_error("Konnte Verzeichnis " + c_make_dir + " nicht loeschen.")
  EndIf

  success = CreateDir(c_make_dir)
  If Not success my_error("Konnte Verzeichnis " + c_make_dir + " nicht anlegen.")

  success = ChangeDir(c_make_dir)
  DebugLog CurrentDir()
  If Not success my_error("Konnte nicht in Verzeichnis " + c_make_dir + " wechseln.")
  Print c_make_dir + " vorbereitet."
EndFunction

'------------------------------------------------------------------------------------
' Sourcen mit svn syncen
'------------------------------------------------------------------------------------
Function sync_files:Int()
  Const c_svnlog:String        = "svnlog.txt"

  Local command:String = "svn checkout http://mscchat.googlecode.com/svn/trunk/" ' > " + c_svnlog
  system_(command)
  Local file_for_check:String = "trunk/guichatclient.bmx"
  Local i:Int = FileType(file_for_check)
  If i = 0 Then my_error(command + " hat nicht funktioniert. Konnte " + file_for_check + " nicht finden.")
  Print "Dateien erfolgreich heruntergeladen."
   
  ' svn Version besorgen
  ?Win32
    command = "cmd /C svnversion trunk > " + c_version_file
  ?Linux
    command = "svnversion trunk > " + c_version_file
  ?
  system_(command)

  Local version:Int = -1
  Local datei:TStream=OpenFile(c_version_file)
  If Not datei Then my_error("Kann Datei " + c_version_file + " nicht finden!")
  Local text:String
  While Not Eof (datei)
    text = ReadLine (datei)
    text = text.Trim()     
    If Not text Then Continue               ' Leerzeilen ignorieren
    version = Int(text)    
  Wend   CloseStream(datei) 
  
  If version = -1 Then
    my_error("Konnte Version der Sourcen nicht bestimmen")
  Else
    Print "Die Quelltext-Version ist: " + version
  EndIf

  Return version
EndFunction

'------------------------------------------------------------------------------------

Function build(action:Int, source_version:Int, ftp_version:Int)
  If action = c_action_ftp And ftp_version >= source_version Then Return ' nichts zu tun

  Print source_version

  ' schreibe Versions-Include
  Const c_versionsdatei:String = "trunk/version.bmx"
  Local datei:TStream = WriteFile(c_versionsdatei)
  If Not datei Then my_error("Kann Datei " + c_versionsdatei + " nicht oeffnen!")
  WriteLine(datei, "const svn_revision:int = " + source_version)
  CloseStream(datei)

  For Local i:Int = 0 To progs.length - 1
    _build_and_check(progs[i][0], exenames[i], Int(progs[i][1])) 
  Next
EndFunction

'------------------------------------------------------------------------------------

Function upload(action:Int, source_version:Int, ftp_version:Int)
  If action = c_action_build Or ( action = c_action_ftp And ftp_version >= source_version ) Then Return ' nichts zu tun
  ' der Upload loescht die alten Versionen
  _upload(source_version)
EndFunction

'------------------------------------------------------------------------------------

Function my_error(msg:String, func:String = Null)
  If func Then 
    Print "~nFEHLER in Funktion " + func + ": " + msg
  Else
    Print "~nFEHLER: " + msg
  EndIf
  End
EndFunction

'------------------------------------------------------------------------------------
Function get_ftp_version:Int(action:Int)
  If action <> c_action_ftp Then Return -1 ' nichts zu tun

  Local ftp:TIgbFtp = New TIgbFtp.Create("superchat")
  Local ver:Int
  Try
    ver = ftp.get_version_on_server("guichatclient")
  Catch ex:String
    my_error(ex, "get_ftp_version")
  EndTry
  If ver < 0 Then
    Print "Keine Version auf dem Server gefunden."
  Else
    Print "Auf dem FTP-Server ist Version: " + ver 
  EndIf
  Return ver
EndFunction

'------------------------------------------------------------------------------------
Function cleanup(action:Int)
  Local dir_to_delete:String = c_make_dir
  ChangeDir(olddir)

  If action = c_action_build Then
    dir_to_delete = dir_to_delete + "/trunk"
  EndIf

  Local success:Int = DeleteDir(dir_to_delete, True)
  If success Then 
    Print dir_to_delete + " geloescht."
  Else
    my_error("Konnte Verzeichnis " + dir_to_delete + "nicht loeschen.")
  EndIf
EndFunction

'------------------------------------------------------------------------------------
Function _upload(version:Int)
  Local ftp:TIgbFtp = New TIgbFtp.Create("superchat")

  Try
    Local prog:String
    For Local i:Int = 0 To progs.length - 1
      prog = c_make_dir + "/" + exenames[i]
      Print "Lade Program " + prog + " in Version " + version + " auf den FTP Server"
      ftp.upload_superchat(prog,version)
    Next
    prog = c_make_dir + "/" + c_version_file
    Print "Lade Datei " + prog + " auf den FTP Server"
    ftp.upload_superchat(prog, 0, False)
  Catch ex:String
    my_error(ex)
  EndTry
EndFunction

'------------------------------------------------------------------------------------
Function _build_and_check(mainprog:String, exename:String, isgui:Int = True)
  Local command:String
  If isgui Then
    command = bmk + " makeapp -a -r -t gui trunk/" + mainprog
  Else
    command = bmk + " makeapp -a -r trunk/" + mainprog
  EndIf
  system_(command)
  Local file_for_check:String = "trunk/" + exename
  Local i:Int = FileType(file_for_check)
  If i = 0 Then my_error(command + " hat nicht funktioniert. Konnte " + file_for_check + " nicht finden.")
  Print file_for_check + " erfolgreich gebaut."

  i = CopyFile(CurrentDir() + "/trunk/" + exename, CurrentDir() + "/" + exename)
  If Not i Then my_error("Konnte " + CurrentDir() + "/trunk/" + exename + " nicht nach " + CurrentDir() + " kopieren." )
  ?Linux ' Kopierte Datei ausfuehrbar machen
  SetFileMode(exename, FileMode(exename) | %001001001 )
  ?
EndFunction